package com.cmsz.order.controller;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.async.DeferredResult;
import org.springframework.web.servlet.ModelAndView;

import com.cmsz.cashier.bean.CashierOrderInoBean;
import com.cmsz.order.remote.BetterRemoteService;
import com.cmsz.order.remote.SignResult;
import com.cmsz.framework.log.LogHandler;
import com.cmsz.framework.util.DateUtil;
import com.cmsz.framework.util.JsonUtil;
import com.cmsz.framework.util.KeyValueUtil;
import com.cmsz.framework.util.SerialNumber;
import com.cmsz.framework.util.XmlUtils;

/**
 * 
 * @author zhoujirong
 *
 */
@Controller
@RequestMapping("/merchant")
public class MerchantAction {

	private static LogHandler logger = LogHandler.getLogger(MerchantAction.class);
	
	@Resource(name="BankSecurityRemoting")
	private BetterRemoteService betterRemoteService;
	@Value("${sinmulator}")
	private String sinmulator;
	
	/**
	 * 模拟商户签名
	 * @param req
	 * @return
	 * @throws IOException
	 */
	@RequestMapping(value = "/sign.action", produces = "text/html; charset=utf-8", method = { RequestMethod.POST,
			RequestMethod.GET })
	public @ResponseBody DeferredResult<String> sign(HttpServletRequest req) throws IOException {
		DeferredResult<String> deferredResult = new DeferredResult<String>();
		if (!"open".equals(sinmulator)) {
			deferredResult.setResult("非法请求，H5网站调试功能已关闭");
			return deferredResult;
		}
		Map<String, String> reqMap = comvertMap(req.getParameterMap());
		String cerId = reqMap.remove("CerID");
		reqMap.remove("SignValue");
		try {
			if (StringUtils.isBlank(cerId)) {
				throw new IllegalArgumentException("CerID不能为空");
			}
			String kv = KeyValueUtil.mapToString(reqMap);
			String jsonStr = betterRemoteService.sign(cerId, kv);
			SignResult signResult = JsonUtil.jsonStr2Obj(jsonStr, SignResult.class);
			deferredResult.setResult(signResult.getSignValue());
		} catch (Exception e) {
			logger.error("模拟商户生成签名失败", e);
			deferredResult.setResult(e.getMessage());
		}
		return deferredResult;
	}
	
	@RequestMapping(value = "/return", produces = "text/html; charset=utf-8", method = { RequestMethod.POST,
			RequestMethod.GET })
	public @ResponseBody ModelAndView cashierReturn(HttpServletRequest req,CashierOrderInoBean orderBean) throws IOException {
		ModelAndView modelAndView = new ModelAndView();
		modelAndView.addObject(orderBean);
		modelAndView.setViewName("mersuccess");
		return modelAndView;
	}
	
	/**
	 * 模拟商户接收商户前置结果通知
	 * @param req
	 * @return
	 * @throws IOException
	 */
	@RequestMapping(value = "/notify.action", produces = "text/html; charset=utf-8", method = { RequestMethod.POST,
			RequestMethod.GET })
	public @ResponseBody DeferredResult<String> notify(HttpServletRequest req) throws IOException {
		DeferredResult<String> deferredResult = new DeferredResult<String>();
		InputStream inStream = req.getInputStream();
		BufferedReader br = new BufferedReader(new InputStreamReader(inStream));
		String line = null;
		StringBuilder sb = new StringBuilder();
		while ((line = br.readLine()) != null) { sb.append(line); }
		final String xmldata = sb.toString();
		logger.info("虚拟商户|MerchantAction|接收到统一支付结果通知",null);
		logger.messageReceive("虚拟商户|MerchantAction|接收到统一支付结果通知:" + xmldata);
		StringBuilder buf = new StringBuilder();
		buf.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?><GPay><Header>");
		buf.append("<ActivityCode>U101_101</ActivityCode>");
		buf.append("<ReqSys>" + XmlUtils.parseNodeValueFromXml("<ReqSys>", "</ReqSys>", xmldata) + "</ReqSys>");
		buf.append("<ReqDate>" + XmlUtils.parseNodeValueFromXml("<ReqDate>", "</ReqDate>", xmldata) + "</ReqDate>");
		buf.append("<ReqTransID>" + XmlUtils.parseNodeValueFromXml("<ReqTransID>", "</ReqTransID>", xmldata) + "</ReqTransID>");
		buf.append("<ReqDateTime>" + XmlUtils.parseNodeValueFromXml("<ReqDateTime>", "</ReqDateTime>", xmldata) + "</ReqDateTime>");
		buf.append("<ActionCode>RSP</ActionCode>");
		buf.append("<RcvSys>" + XmlUtils.parseNodeValueFromXml("<RcvSys>", "</RcvSys>", xmldata) + "</RcvSys>");
		buf.append("<RcvDate>" + DateUtil.getCurrDate() + "</RcvDate>");
		buf.append("<RcvTransID>" + SerialNumber.generateRandomSerial(32) + "</RcvTransID>");
		buf.append("<RcvDateTime>" + DateUtil.getDateyyyyMMddHHmmss() + "</RcvDateTime>");
		buf.append("<RspCode>010A00</RspCode>");
		buf.append("<RspDesc>成功</RspDesc>");
		buf.append("</Header>");
		String body = XmlUtils.parseNodeValueFromXml("<Body>", "</Body>", xmldata);
		body = trimCustomParam(body);
		buf.append("<Body>" + body + "</Body>");
		buf.append("<Sign><CerID></CerID><SignValue></SignValue></Sign></GPay>");
		String result = buf.toString();
		logger.info("虚拟商户|MerchantAction|向统一支付响应应答报文",null);
		logger.messageSend("虚拟商户|MerchantAction|向统一支付响应应答报文" + result);
		deferredResult.setResult(result);
		return deferredResult;	
	}
	
	/**
	 * 将http请求参数转换成Map<String, String>
	 * @param map
	 * @return
	 */
	private Map<String, String> comvertMap(Map<String, String[]> map) {
		Map<String, String> newMap = new HashMap<String, String>();
		Iterator<Entry<String, String[]>> it = map.entrySet().iterator();
		while (it.hasNext()) {
			Entry<String, String[]> entry = it.next();
			String key = entry.getKey();
			String[] value = entry.getValue();
			newMap.put(key, value[0]);
		}
		return newMap;
	}
	
	private String trimCustomParam(String text) {
		int a = text.indexOf("<CustomParam>");
		int b = text.indexOf("</CustomParam>");
		if (a!=-1 && b!=-1) {
			text = text.substring(0, a) + text.substring(b + "</CustomParam>".length(), text.length());
		}
		return text;
	}
}
